/*
 * 
 * 
 */
package com.wandian.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.Writer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.QuietWriter;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;

/**
 *
 * @date 2011-10-26, 13:39:34
 * @author long@7road.com
 * @description FileAppender类：重写log4j日志接口，实现特定格式的日志存储
 */
public class FileAppender extends WriterAppender {



    /**
    The default constructor does not do anything.
     */
    public FileAppender() {
        setImmediateFlush(true);
    }
    
    public void setFile(String file) {
        // Trim spaces from both ends. The users probably does not want
        // trailing spaces in file names.
        String val = file.trim();
        fileName = val;
    }

    /**
    Returns the value of the <b>Append</b> option.
     */
    public boolean getAppend() {
        return fileAppend;
    }

    /** Returns the value of the <b>File</b> option. */
    public String getFile() {
        return fileName;
    }

    /**
    If the value of <b>File</b> is not <code>null</code>, then {@link
    #setFile} is called with the values of <b>File</b>  and
    <b>Append</b> properties.
    
    @since 0.8.1 */
    public void activateOptions() {
//        if (fileName != null) {
//            try {
//                setFile(fileName, fileAppend, bufferedIO, bufferSize);
//            } catch (java.io.IOException e) {
//                errorHandler.error("setFile(" + fileName + "," + fileAppend + ") call failed.",
//                        e, ErrorCode.FILE_OPEN_FAILURE);
//            }
//        } else {
//            //LogLog.error("File option not set for appender ["+name+"].");
//            LogLog.warn("File option not set for appender [" + name + "].");
//            LogLog.warn("Are you using FileAppender instead of ConsoleAppender?");
//        }
    }

    /**
    Closes the previously opened file.
     */
    protected void closeFile() {
        if (this.qw != null) {
            try {
                this.qw.close();
            } catch (java.io.IOException e) {
                if (e instanceof InterruptedIOException) {
                    Thread.currentThread().interrupt();
                }
                // Exceptionally, it does not make sense to delegate to an
                // ErrorHandler. Since a closed appender is basically dead.
                LogLog.error("Could not close " + qw, e);
            }
        }
    }

    /**
    Get the value of the <b>BufferedIO</b> option.
    
    <p>BufferedIO will significatnly increase performance on heavily
    loaded systems.
    
     */
    public boolean getBufferedIO() {
        return this.bufferedIO;
    }

    /**
    Get the size of the IO buffer.
     */
    public int getBufferSize() {
        return this.bufferSize;
    }

    /**
    The <b>Append</b> option takes a boolean value. It is set to
    <code>true</code> by default. If true, then <code>File</code>
    will be opened in append mode by {@link #setFile setFile} (see
    above). Otherwise, {@link #setFile setFile} will open
    <code>File</code> in truncate mode.
    
    <p>Note: Actual opening of the file is made when {@link
    #activateOptions} is called, not when the options are set.
     */
    public void setAppend(boolean flag) {
        fileAppend = flag;
    }

    /**
    The <b>BufferedIO</b> option takes a boolean value. It is set to
    <code>false</code> by default. If true, then <code>File</code>
    will be opened and the resulting {@link java.io.Writer} wrapped
    around a {@link BufferedWriter}.
    
    BufferedIO will significatnly increase performance on heavily
    loaded systems.
    
     */
    public void setBufferedIO(boolean bufferedIO) {
        this.bufferedIO = bufferedIO;
        if (bufferedIO) {
            immediateFlush = false;
        }
    }

    /**
    Set the size of the IO buffer.
     */
    public void setBufferSize(int bufferSize) {
        this.bufferSize = bufferSize;
    }    


  
    public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
            throws IOException, IllegalAccessException {
        reset();
        FileOutputStream ostream = null;
        try {       
            String curerrentFile = GetCurrentFile(fileName);
            curerrentFile=PathUtil.getAasolutePath(curerrentFile);
            System.out.println("log4j:"+curerrentFile);
            ostream = new FileOutputStream(curerrentFile, append);
        } catch (FileNotFoundException ex) {
            String parentName = new File(fileName).getParent();
            if (parentName != null) {
                File parentDir = new File(parentName);
                if (!parentDir.exists() && parentDir.mkdirs()) {
                    String curerrentFile = GetCurrentFile(fileName);
                    ostream = new FileOutputStream(curerrentFile, append);
                } else {
                    throw ex;
                }
            } else {
                throw ex;
            }
        }
        Writer fw = createWriter(ostream);
        this.setQWForFiles(fw);
        writeHeader();
        LogLog.debug("setFile ended");
        
    }    
 

    /**
    Sets the quiet writer being used.
    
    This method is overriden by {@link RollingFileAppender}.
     */
    protected void setQWForFiles(Writer writer) {
        this.qw = new QuietWriter(writer, errorHandler);
    }

    /**
    Close any previously opened file and call the parent's
    <code>reset</code>.  */
    protected void reset() {
        closeFile();
        super.reset();
    }
}
